package com.lb.base.util;

import org.apache.commons.io.FileUtils;
import org.lionsoul.ip2region.xdb.Searcher;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * @author libin
 */
public class IpHelper {
    private static final String region2File = "ip2region.xdb";

    private static byte[] vIndex;
    private static String dbPath;

    static {
        buildVIndex();
    }

    private static void buildVIndex() {
        dbPath = IpHelper.class.getClassLoader().getResource(region2File).getPath();

        try {
            File file = new File(dbPath);
            if (!file.exists()) {
                String tmpDir = System.getProperties().getProperty("java.io.tmpdir");
                dbPath = tmpDir + region2File;
                file = new File(dbPath);
                FileUtils.copyInputStreamToFile(IpHelper.class.getClassLoader().getResourceAsStream("classpath:" + region2File), file);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.printf("failed to copy index from `%s`: %s\n", dbPath, ex);
        }


        //从 dbPath 中预先加载 VectorIndex 缓存，并且把这个得到的数据作为全局变量，后续反复使用。
        try {
            vIndex = Searcher.loadVectorIndexFromFile(dbPath);
        } catch (Exception e) {
            System.out.printf("failed to load vector index from `%s`: %s\n", dbPath, e);
        }
    }

    public static String findRegionByIp(String ip) {
        //创建 searcher 对象
        String nonTips = "未知-未知";
        Searcher searcher = null;
        try {
            searcher = Searcher.newWithVectorIndex(dbPath, vIndex);
        } catch (IOException e) {
            System.out.printf("failed to create searcher with `%s`: %s\n", dbPath, e);
            return nonTips;
        }
        //查询
        try {
            String location = searcher.search(ip.trim());
            String[] split = location.split("\\|");
            return split[0] + split[2] + "-" + split[3];
        } catch (Exception e) {
            System.out.printf("failed to search(%s): %s\n", ip, e);
        } finally {
            //关闭资源
            try {
                searcher.close();
            } catch (IOException ex) {
                System.out.printf("failed to close search: %s\n", ex);
            }

        }
        return nonTips;
    }

    /**
     * 获取IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals("127.0.0.1")) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
                // = 15
                if (ipAddress.indexOf(",") > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
            ipAddress = "";
        }
        // ipAddress = this.getRequest().getRemoteAddr();

        return ipAddress;
    }

    public static void main(String[] args) {
        System.err.printf("parsing ipaddress[%s] to location: %s ", "120.42.192.81", findRegionByIp("120.42.192.81"));
    }
}
